package com.free.semantic.core.impl.demo;

import com.free.semantic.common.LocatorNode;
import com.free.semantic.common.Ls;
import com.free.semantic.common.ParamNode;
import com.free.semantic.common.RelationChain;
import com.free.semantic.core.ConceptInstanceManage;
import com.free.semantic.core.ConceptManage;
import com.free.semantic.core.impl.BaseTest;
import com.free.semantic.core.impl.ConceptInstanceManageImpl;
import com.free.semantic.req.RelationDefineGroup;
import com.free.semantic.utils.Utils;
import org.junit.jupiter.api.Test;

import java.util.List;

import static com.free.semantic.common.RangeObj.more;

/**
 * 语义网络demo演示，层级结构差异下 实现信息互通
 */
public class Demo2_countryAndCity extends BaseTest {


    @Test
    public void test() {

        /**
         *  定义关系：
         *  relation 包含(A,B)
         *     [包含]:A->B=[0,) //代表 针对任意一个A，都可以找到 [0,)个B与之对应
         *     [被包含]:B->A=1  //代表 针对任意一个B，都可以找到 1个A与之对应
         */
        RelationDefineGroup group = new RelationDefineGroup();
        // relation 包含(A,B)
        defineRelation(group, "包含",
                defineItem(oneObj("A"), moreObj("B"))); //B->A=1  //代表 针对任意一个B，都可以找到 1个A与之对应

        //  使用包含关系 定义一个语义网络
        ConceptManage provinceAndCityModel = getConceptManage(group);
        //object 国家 省份 城市
        object(provinceAndCityModel, "国家", "省份", "城市");
        //包含(国家,省份)
        createRelation(provinceAndCityModel, "包含", "国家", "省份");
        //包含(省份,城市)
        createRelation(provinceAndCityModel, "包含", "省份", "城市");

        /**
         * 创建模型的一个实现，并且实现 国家，省份 和城市之间的互相查询
         */
        ConceptInstanceManage modelInstance = new ConceptInstanceManageImpl(provinceAndCityModel,
                buildMap("国家", "省份", new String[][]{
                        {"中国", "广东"},
                        {"中国", "山西"},
                        {"中国", "浙江"}}),
                buildMap("省份", "城市", new String[][]{
                        {"浙江", "杭州"}, {"浙江", "金华"},
                        {"山西", "长治"}, {"山西", "运城"},
                        {"广东", "广州"}, {"广东", "珠海"}}));

        // 查询 从国家到城市的路径
        List<RelationChain> relationChains = modelInstance.concept().findAllRelationChain(Ls.of("国家"), "城市");

        print(relationChains);// 输出的路径是  中国->省份->城市

        // 查询中国的城市有哪些
        List<String> city = modelInstance.takePath(Ls.of(new ParamNode("国家", "中国")), "城市");
        System.out.println(city);

        /**
         * 定义
         * relation include(A,B)
         *     [include]:A->B=[0,) //代表 针对任意一个A，都可以找到 [0,)个B与之对应
         *     [included]:B->A=1  //代表 针对任意一个B，都可以找到 1个A与之对应
         */
        RelationDefineGroup include = new RelationDefineGroup();
        //relation include(A,B)
        defineRelation(include, "include",
                defineItem(oneObj("A"), moreObj("B"))); //代表 针对任意一个B，都可以找到 1个A与之对应

        ConceptManage anotherModel = getConceptManage(include);
        //object country city
        object(anotherModel, "country", "city");

        //include(country,city)
        createRelation(anotherModel, "include", "country", "city");
        // 创建语义网络的一个无实现的一个空实例
        ConceptInstanceManage anotherModelInstance = new ConceptInstanceManageImpl(anotherModel);


        ConceptInstanceManage copy = Utils.copy(modelInstance);
        Utils.mergerConcept(copy, anotherModelInstance);

        Utils.equalConceptMap(copy, Ls.of("country"), "city", Ls.of("国家"), "城市");

        List<String> anotherCityList = copy.goByLocatorNode(Ls.of(new ParamNode("country", "中国"), new LocatorNode("省份")), more("city"));
        assert city.equals(anotherCityList);
    }

}
